#include "stdafx.h"
#include "RankListWnd.h"
#include "field_define.h"
#include "GoodsManager.h"
#include "helper/SListViewItemLocator.h"
#include "helper/SMenuEx.h"

XRankListWnd::XRankListWnd(): XWnd(_T("LAYOUT:XML_RANK_WND")) {
}

XRankListWnd::~XRankListWnd() {
}

BOOL XRankListWnd::OnInitDialog(HWND wndFocus, LPARAM lInitParam) {
    __super::OnInitDialog(wndFocus, lInitParam);
    m_pListView = FindChildByName2<SOUI::SMCListView>(L"lv_lst");
    if (m_pListView) {
        SOUI::IListViewItemLocator *pItemLocator = new  SOUI::SListViewItemLocatorFix(SOUI::SLayoutSize(32,
                SOUI::SLayoutSize::px));
        m_pListView->SetItemLocator(pItemLocator);
        m_pListView->SetAdapter(&m_codeListAdapter);
        pItemLocator->Release();
        
        m_pListView->GetEventSet()->subscribeEvent(SOUI::EventScroll::EventID,
                SOUI::Subscriber(&XRankListWnd::OnVScroll, this));
                
        m_pListView->GetEventSet()->subscribeEvent(SOUI::EventItemPanelHover::EventID,
                SOUI::Subscriber(&XRankListWnd::OnItemHover, this));
                
        m_pListView->GetEventSet()->subscribeEvent(SOUI::EventItemPanelLeave::EventID,
                SOUI::Subscriber(&XRankListWnd::OnItemLeave, this));
                
        m_pListView->GetEventSet()->subscribeEvent(SOUI::EventLVItemDBClick::EventID,
                SOUI::Subscriber(&XRankListWnd::OnItemDBClick, this));
                
        m_pListView->GetEventSet()->subscribeEvent(SOUI::EventLVSelChanged::EventID,
                SOUI::Subscriber(&XRankListWnd::OnItemSelChanged, this));
                
        m_pListView->GetEventSet()->subscribeEvent(SOUI::EVT_CTXMENU, SOUI::Subscriber(&XRankListWnd::OnEventCtxMenu, this));
        
        auto header = m_pListView->GetHeaderCtrl();
        header->GetEventSet()->subscribeEvent(SOUI::EventHeaderItemSwap::EventID,
                                              SOUI::Subscriber(&XRankListWnd::OnItemHeaderSwap, this));
                                              
        m_pListView->setLoadMore([this]() {
            if (m_codes.empty()) {
                return;
            }
            
            int curPage = m_curPage + 1;
            if (reqData(curPage, 20)) {
                m_curPage = curPage;
            }
        });
    }
    
    m_pListSymbol = FindChildByName2<SOUI::SMCListView>(L"lv_symbol");
    if (m_pListSymbol) {
        SOUI::IListViewItemLocator *pItemLocator = new  SOUI::SListViewItemLocatorFix(SOUI::SLayoutSize(32,
                SOUI::SLayoutSize::px));
        m_pListSymbol->SetItemLocator(pItemLocator);
        m_pListSymbol->SetAdapter(&m_symbolAdapter);
        pItemLocator->Release();
        
        m_pListSymbol->GetEventSet()->subscribeEvent(SOUI::EventScroll::EventID,
                SOUI::Subscriber(&XRankListWnd::OnVScroll, this));
                
        m_pListSymbol->GetEventSet()->subscribeEvent(SOUI::EventItemPanelHover::EventID,
                SOUI::Subscriber(&XRankListWnd::OnItemHover, this));
                
        m_pListSymbol->GetEventSet()->subscribeEvent(SOUI::EventItemPanelLeave::EventID,
                SOUI::Subscriber(&XRankListWnd::OnItemLeave, this));
                
        m_pListSymbol->GetEventSet()->subscribeEvent(SOUI::EventLVItemDBClick::EventID,
                SOUI::Subscriber(&XRankListWnd::OnItemDBClick, this));
                
        m_pListSymbol->GetEventSet()->subscribeEvent(SOUI::EventLVSelChanged::EventID,
                SOUI::Subscriber(&XRankListWnd::OnItemSelChanged, this));
                
        m_pListSymbol->GetEventSet()->subscribeEvent(SOUI::EVT_CTXMENU, SOUI::Subscriber(&XRankListWnd::OnEventCtxMenu, this));
    }
    
    
    auto scroll_h = FindChildByName2<SOUI::SScrollBar>(L"scroll_h");
    if (scroll_h) {
        auto sbInfo = m_pListView->GetScrollBarInfo(FALSE);
        SCROLLINFO info;
        memcpy(&info, sbInfo, sizeof(SCROLLINFO));
        info.fMask = SIF_ALL;
        scroll_h->SSendMessage(SBM_SETSCROLLINFO, TRUE, (LPARAM)&info);
        scroll_h->GetEventSet()->subscribeEvent(SOUI::EventScroll::EventID,
                                                SOUI::Subscriber(&XRankListWnd::OnHScroll, this));
    }
    
    m_symbolAdapter.notifyDataSetChanged();
    m_codeListAdapter.notifyDataSetChanged();
    
    return FALSE;
}

void XRankListWnd::OnLogin() {

}

void XRankListWnd::OnLogout() {

}

void XRankListWnd::OnReqData() {
    reqData(m_curPage, 40);
}

void XRankListWnd::OnDelData() {
    hideStatus();
}

bool XRankListWnd::OnHScroll(SOUI::EventScroll *pEvt) {
    pEvt->bubbleUp = false;
    auto scroll_h = FindChildByName2<SOUI::SScrollBar>(L"scroll_h");
    if (scroll_h && m_pListView) {
        m_pListView->SetScrollPos(FALSE, scroll_h->GetPos(), TRUE);
    }
    
    UpdateWindow();
    return false;
}

bool XRankListWnd::OnVScroll(SOUI::EventScroll *pEvt) {
    pEvt->bubbleUp = false;
    
    if (pEvt->bVertical) {
    
        SOUI::SMCListView *pListView = (SOUI::SMCListView *)pEvt->sender;
        if (pListView) {
            auto sbInfo = pListView->GetScrollBarInfo(TRUE);
            
            SCROLLINFO info;
            info.nPage = sbInfo->nPage;
            info.nMin = sbInfo->nMin;
            info.nMax = sbInfo->nMax;
            info.fMask = SIF_PAGE | SIF_RANGE;
            
            if (pListView != m_pListSymbol) {
                m_pListSymbol->SetScrollInfo(info, TRUE);
                m_pListSymbol->SSendMessage(WM_MSG_SYNC_VSCROLL, pEvt->nSbCode, pEvt->nPos);
            } else if (pListView != m_pListView) {
                m_pListView->SetScrollInfo(info, TRUE);
                m_pListView->SSendMessage(WM_MSG_SYNC_VSCROLL, pEvt->nSbCode, pEvt->nPos);
            }
            UpdateWindow();
        }
    }
    return false;
}

bool XRankListWnd::OnItemHover(SOUI::EventItemPanelHover *pEvt) {
    pEvt->bubbleUp = false;
    
    if (m_pListView) {
        auto panel = m_pListView->GetItemPanel(pEvt->wParam);
        
        if (panel && panel != pEvt->sender) {
            panel->ModifyState(SOUI::WndState_Hover, 0, TRUE);
        }
    }
    
    if (m_pListSymbol) {
        auto panel = m_pListSymbol->GetItemPanel(pEvt->wParam);
        if (panel && panel != pEvt->sender) {
            panel->ModifyState(SOUI::WndState_Hover, 0, TRUE);
        }
    }
    
    return true;
}

bool XRankListWnd::OnItemLeave(SOUI::EventItemPanelLeave *pEvt) {
    SOUI::SItemPanel *panelSender = (SOUI::SItemPanel *)pEvt->sender;
    auto idx = panelSender->GetItemIndex();
    auto panel = m_pListView->GetItemPanel(idx);
    
    if (panel && panel != panelSender) {
        panel->ModifyState(0, SOUI::WndState_Hover, TRUE);
    }
    
    if (m_pListSymbol) {
        panel = m_pListSymbol->GetItemPanel(idx);
        if (panel && panel != panelSender) {
            panel->ModifyState(0, SOUI::WndState_Hover, TRUE);
        }
    }
    return true;
}

bool XRankListWnd::OnItemHeaderSwap(SOUI::EventHeaderItemSwap *pEvt) {
    auto headerCtrl = m_pListView->GetHeaderCtrl();
    int nCount = headerCtrl->GetItemCount();
    
    /*Json::Value jsHeaderDatas;
    SOUI::SHDITEM  shItem;
    shItem.mask = SHDI_ORDER | SHDI_TEXT_RAW | SHDI_WEIGHT | SHDI_WIDTH;
    SOUI::SStringA ssText;
    for (size_t i = 0; i < nCount; i++) {
        headerCtrl->GetItem(i, &shItem);
        Json::Value item;
        item["o"] = shItem.iOrder;
        item["x"] = shItem.cx;
        item["w"] = shItem.fWeight;
        item["t"] = CommonUtil::ToUTF8(shItem.strText.GetText(TRUE).c_str());
        ssText.AppendFormat("%s|", item["t"].asString().c_str());
        jsHeaderDatas.append(item);
    }*/
    
    return false;
}


bool XRankListWnd::OnItemDBClick(SOUI::EventLVItemDBClick *pEvt) {

    if (m_pListView == pEvt->sender) {
        return false;
    }
    if (m_pListView->GetSel() != pEvt->nCurSel) {
        m_pListView->SetSel(pEvt->nCurSel, FALSE);
    }
    
    if (m_pListSymbol && m_pListSymbol->GetSel() != pEvt->nCurSel) {
        m_pListSymbol->SetSel(pEvt->nCurSel, FALSE);
    }
    
    return false;
}

bool XRankListWnd::OnItemSelChanged(SOUI::EventLVSelChanged *pEvt) {

    pEvt->bubbleUp = false;
    
    if (m_pListSymbol && m_pListSymbol->GetSel() != pEvt->iNewSel) {
        m_pListSymbol->SetSel(pEvt->iNewSel, FALSE);
    }
    if (m_pListView && m_pListView->GetSel() != pEvt->iNewSel) {
        m_pListView->SetSel(pEvt->iNewSel, FALSE);
    }
    return false;
}

bool XRankListWnd::OnEventCtxMenu(SOUI::EventCtxMenu *pEvt) {

    SOUI::CPoint ptCursor = pEvt->pt;
    ClientToScreen(&ptCursor);
    //UA_POST(UAID_1_1_9, "");
    SOUI::SMCListView *pList = (SOUI::SMCListView *)pEvt->sender;
    if (pList) {
        auto *pPanel = pList->HitTest(SOUI::CPoint(pEvt->pt));
        if (pPanel == nullptr) {
            return false;
        }
        
        /* SOUI::SMenuEx menu;
         menu.LoadMenu(_T("SMenu:positionlist"), m_hWnd);
         if (pPanel != nullptr ) {
             int nCmdID = menu.TrackPopupMenu(TPM_RETURNCMD, ptCursor.x + 8, ptCursor.y + 12, m_hWnd);
             auto pData = menu.GetMenuItem(nCmdID);
        
             switch (nCmdID) {
                 default:
                     break;
             }
         }*/
    }
    
    return false;
}


void XRankListWnd::OnSize(UINT type, SOUI::CSize sz) {
    __super::OnSize(type, sz);
    syncScrollBar();
    OnReqData();
}

void XRankListWnd::syncScrollBar() {
    auto scroll_h = FindChildByName2<SOUI::SScrollBar>(L"scroll_h");
    if (scroll_h && m_pListView) {
        auto sbInfo = m_pListView->GetScrollBarInfo(FALSE);
        if (sbInfo->nPos <= 0 && sbInfo->nPage > sbInfo->nMax ) {
            scroll_h->SetVisible(false, true);
        } else {
            SCROLLINFO info;
            memcpy(&info, sbInfo, sizeof(SCROLLINFO));
            info.fMask = SIF_ALL;
            scroll_h->SSendMessage(SBM_SETSCROLLINFO, TRUE, (LPARAM)&info);
        }
    }
}

bool XRankListWnd::reqData(int reqPage, int pageSize) {
    if (m_in_request || !m_flag) {
        return false;
    }
    
    m_in_request = true;
    if (reqPage > 1) {
        showStatus(STATUS_TIPS_TYPE::STATUS_LOAD_MORE);
    } else {
        showStatus(STATUS_TIPS_TYPE::STATUS_LOADING);
    }
    
    SOUI::SStringA urlReq;
    urlReq.Format("http://vip.stock.finance.sina.com.cn/quotes_service/api/json_v2.php/Market_Center.getHQNodeData?page=%d&num=%d&sort=symbol&asc=1&node=sh_a&symbol=&_s_r_a=init",
                  reqPage, pageSize);
                  
    xHttpClient.Get(cpr::Url(urlReq.c_str()), m_flag, [this](const XResponse & resp) {
        m_in_request = false;
        hideStatus();
        if (resp.isOK()) {
            auto jsonResp = resp.getJson();
            for (size_t i = 0; i < jsonResp.size(); i++) {
                auto jsItem = jsonResp[i];
                auto code = atoi(jsItem["code"].asString().c_str());
                if (code > 0) {
                    auto pGoods = xGoodsManager.getGoods(code, false);
                    if ( pGoods == nullptr) {
                        pGoods = xGoodsManager.createGoods(code);
                        
                        pGoods->setValue(FID_NAME, jsItem["name"].asString());
                        pGoods->setValue(FID_NAMECODE, jsItem["symbol"].asString());
                        pGoods->setValue(FID_PRICE, jsItem["trade"].asString());
                        
                        auto pricechange = jsItem["pricechange"].asDouble();
                        auto changepercent = jsItem["changepercent"].asDouble();
                        
                        pGoods->setValue(FID_ZHANGDIE, CommonUtil::XToStingValue(pricechange, 3));
                        pGoods->setValue(FID_ZDF, CommonUtil::XToStingValue(changepercent, 3) + "%");
                        pGoods->setValue(FID_VOLUME, jsItem["volume"].asString());
                        pGoods->setValue(FID_AMOUNT, jsItem["amount"].asString());
                        pGoods->setValue(FID_BUY_1, jsItem["buy"].asString());
                        pGoods->setValue(FID_SELL_1, jsItem["sell"].asString());
                        pGoods->setValue(FID_PREV_CLOSE, jsItem["settlement"].asString());
                        pGoods->setValue(FID_OPEN, jsItem["open"].asString());
                        pGoods->setValue(FID_HIGH, jsItem["high"].asString());
                        pGoods->setValue(FID_LOW, jsItem["low"].asString());
                        
                        m_codes.push_back(code);
                        m_codeListAdapter.m_goodsList.push_back(pGoods);
                        m_symbolAdapter.m_goodsList = m_codeListAdapter.m_goodsList;
                    }
                }
            }
            
            m_symbolAdapter.notifyDataSetChanged();
            m_codeListAdapter.notifyDataSetChanged();
        }
        
        if (m_codes.empty()) {
            showStatus(STATUS_TIPS_TYPE::STATUS_EMPTY_CONTENT);
        }
    });
    
    return true;
}

void XRankListWnd::OnTimer(UINT_PTR idEvent) {
    __super::OnTimer(idEvent);
}
